#pragma once

#include "noncopyable.h"
#include "Timestamp.h"
#include "CurrentThread.h"

#include <vector>
#include <functional>
#include <memory>
#include <atomic>
#include <mutex>

class Channel;
class Poller;

class EventLoop : noncopyable
{
public:
    using Functor = std::function<void()>;
    // 构造析构
    EventLoop();
    ~EventLoop();
    // 开启/退出事件循环
    void loop();
    void quit();

    // 在当前loop中执行回调函数
    void runInLoop(Functor cb);
    // 将回调函数放入队列，唤醒loop的线程进行执行
    void queueInLoop(Functor cb);
    // 唤醒loop所在线程
    void wakeup();
    // 更新channel
    void updateChannel(Channel *channel);
    void removeChannel(Channel *channel);
    bool hasChannel(Channel *channel);

    // 判断EventLoop对象是否在自己的线程中
    bool isInLoopThread() const
    {
        return threadId_ == CurrentThread::tid();
    }
    // 返回poll就绪事件获取的时间戳
    Timestamp pollReturnTime() const
    {
        return pollReturnTime_;
    }

private:
    void handleRead();
    void doPendingFunctors();

    using ChannelList = std::vector<Channel *>;

    // 标记当前EventLoop的线程id
    const pid_t threadId_;

    // 记录是否在循环，退出，在调用回调函数
    std::atomic_bool looping_;
    std::atomic_bool quit_;
    std::atomic_bool callingPendingFunctors_;

    int wakeupFd_; // 事件对象的fd，用户线程间的notify机制

    Timestamp pollReturnTime_; // IO复用wait时间戳

    std::unique_ptr<Poller> poller_;         // IO复用-事件分发器
    std::unique_ptr<Channel> wakeupChannel_; // 线程间notify
    ChannelList activeChannels_;             // 就绪Channel事件
    std::vector<Functor> pendingFunctors_;   // 回调函数列表

    std::mutex mutex_; // 保证回调列表线程安全
};